package ffte.evaluate.vectors

import breeze.math.Complex
import scala.util.Random._
import ffte.algorithm.FFTMisc

import ffte.native.{NFFT,NIFFT,Native}
import ffte.algorithm.FFTGen

/**
 * Native FFT test vector generator
 *
 * This class generates test vectors using native FFT implementations
 * as the reference for validation. It provides accurate reference
 * outputs for comparing against hardware implementations.
 *
 * Key Features:
 * - Uses Winograd FFT algorithm for reference generation
 * - Supports both forward and inverse FFT modes
 * - Generates various test patterns (random, noise, impulse)
 * - Provides accurate reference for hardware validation
 *
 * Test Patterns:
 * - TV: Random data vectors for general testing
 * - NV: Noise vectors with specific frequency components
 * - IV: Impulse vectors for frequency response testing
 *
 * @param N Transform size
 * @param S Scaling factor for fixed-point simulation
 * @param inv Flag for inverse FFT mode (default: false)
 */
case class NativeVector(N:Int,S:Int,inv:Boolean=false) extends genVector {

    // Configure FFT generation to use Winograd method
    FFTGen.Winograd

    /** Generated FFT structure for native implementation */
    val fp = FFTGen.gen[Native](N)

    /** Forward FFT implementation */
    val t2f = new NFFT(fp,S)

    /** Inverse FFT implementation */
    val f2t = new NIFFT(fp,S)

    /**
     * Generate random test vectors
     *
     * Creates random input data and computes the corresponding FFT
     * output using the native reference implementation.
     *
     * @param sx Scaling factor for input amplitude
     * @return Test vectors with random input and computed output
     */
    def TV(sx:Int) = {
        val x = new Array[Complex](N)
        for (i <- 0 until N) {
            x(i) = Complex(nextDouble()-0.5,nextDouble()-0.5)*(1<<sx)
        }
        val y = if(inv) f2t.transform(x) else t2f.transform(x)
        TestVectors(TestVectors.fromVC(x,0),TestVectors.fromVC(y,0))
    }

    /**
     * Generate noise test vectors
     *
     * Creates frequency-domain noise vectors and computes the corresponding
     * time-domain signals using inverse FFT. Useful for testing time-domain
     * response characteristics.
     *
     * @param k Frequency index for noise component
     * @param s Additional scaling factor
     * @return Test vectors with noise input and computed output
     */
    def NV(k:Int,s:Int) = {
		val y = new Array[Complex](N)
		for (i <- 0 until N) {
			y(i) = Complex(0.0,0.0)
		}
		y(k) = Complex(1.0/128.0,0.0)*(1<<(S+s))
		val x = if(inv) t2f.transform(y) else f2t.transform(y)
		TestVectors(TestVectors.fromVC(x,0),TestVectors.fromVC(y,0))
	}

    /**
     * Generate impulse test vectors
     *
     * Creates frequency-domain impulse vectors and computes the corresponding
     * time-domain signals. Useful for testing impulse response and system
     * characteristics.
     *
     * @param k Frequency index for impulse component
     * @param s Additional scaling factor
     * @return Test vectors with impulse input and computed output
     */
    def IV(k:Int,s:Int) = {
		val y = new Array[Complex](N)
		for (i <- 0 until N) {
			y(i) = Complex(0.0,0.0)
		}
		y(k) = Complex(0.0,1.0/128.0)*(1<<(S+s))
		val x = if(inv) t2f.transform(y) else f2t.transform(y)
		TestVectors(TestVectors.fromVC(x,0),TestVectors.fromVC(y,0))
	}
}
